﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace MLOCore.Utility
{
    public abstract class ID3Reader
    {
        internal abstract bool CanProcessFile(string fileName);

        internal abstract ID3Information ProcessFile(string fileName);

        #region static

        private static List<ID3Reader> _availableReaders;

        public static ID3Information Process(string file)
        {
            ID3Information toReturn = ID3Information.Empty;

            if (_availableReaders == null)
            {
                InitReaders();
            }

            foreach (ID3Reader reader in _availableReaders)
            {
                if (reader.CanProcessFile(file))
                {
                    toReturn = reader.ProcessFile(file);
                    break;
                }
            }

            return toReturn;
        }

        public static void RegisterID3Reader(ID3Reader id3Reader)
        {
            if (_availableReaders == null)
            {
                InitReaders();
            }

            _availableReaders.Add(id3Reader);
        }

        public static bool CanProcess(string file)
        {
            bool toReturn = false;

            if (_availableReaders == null)
            {
                InitReaders();
            }

            foreach (ID3Reader reader in _availableReaders)
            {
                if (reader.CanProcessFile(file))
                {
                    toReturn = true;
                    break;
                }
            }

            return toReturn;
        }

        private static void InitReaders()
        {
            Assembly asm = System.Reflection.Assembly.GetAssembly(typeof(ID3Reader));
            List<Type> types = new List<Type>(asm.GetTypes());

            List<Type> foundID3Readers = types.FindAll((Predicate<Type>) delegate(Type item) {
                return item.IsSubclassOf(typeof(ID3Reader));
            });

            _availableReaders = new List<ID3Reader>();
            
            foundID3Readers.ForEach((Action<Type>)delegate(Type item)
            {
                if (!item.IsAbstract)
                    _availableReaders.Add((ID3Reader) Activator.CreateInstance(item));
            });
        }

        #endregion



    }
}
